'''
Created on 10/04/2013

@author: mirta
'''

from flask import Blueprint
from flask import request
from flask import render_template
from flask import flash
from flask import redirect
from flask import url_for

from app import db

from app.wtforms.rol_forms import RolBuscar
from app.wtforms.rol_forms import RolEditable
from app.wtforms.rol_forms import RolNoEditable

from app.models.rol import Rol
from app.models.permiso import Permiso
from app.models.usuario import Usuario

from app.security import permission


mod = Blueprint('roles', __name__, url_prefix='/rol')

#Lista de los nombre de los roles por defecto del sistema
roles_por_defecto = ['Administrador de Sistema', 'Lider de Proyecto']



@mod.route('/administracion/', methods=['GET', 'POST'])
@permission('ADMINISTRACION_ROLES')
def administracion_rol():
    """
    Muestra en pantalla los roles que existen en la base de datos.
    Si no recibe algun filtro como parametro, lista todos los roles.
    Si recibe algun filtro, muestra los roles que cumplen con el filtro indicado
    """
   
    # Obtenemos el formulario
    form =  RolBuscar(request.form)   
      
    # Obtenemos el filtro
    nombreFilter = form.nombre.data
    if(nombreFilter == None):
        nombreFilter = '' 
    
    # Recuperamor de la base de datos lo roles que coinciden con el filtro
    roles = Rol.query.filter(Rol.nombre.like( '%'+nombreFilter+'%' ))
    roles = roles.all()    
        
    return render_template('rol/administracion_rol.html', form = form, roles = roles)


@mod.route('/crear/', methods=['GET', 'POST'])
@permission('CREAR_ROL')
def crear_rol():
    """
    Muestra en pantalla el formulario de creacion de roles, valida los datos ingresados por
    el usuario, hace las validaciones de que el nombre del usuario nuevo no exista ya en el
    sistema y se hayan ingresado los datos obligatorios. Luego almacena en base de datos
    """
    
    # Obtenemos el formulario
    form = RolEditable(request.form)
        
    # Obtenemos todos los permisos existentes en la base de datos
    permisos =Permiso.query.all()
    
    # Hacemos una tupla con el nombre del permisos y su id
    lista_permisos=[]
    for permiso in permisos:
        if permiso.entidad == None:
            aux = ""
        else:
            aux= permiso.entidad.nombre
            
        lista_permisos.append((permiso.id, permiso.nombre+" "+aux))
    
    # Asignamos esa tupla de permisos a la lista que va a ser visualizada en el checkbox  
    form.permisos.choices = lista_permisos
    
    # Se valida los datos ingresados en el formulario
    if form.validate_on_submit():
        
        # Obtenemos todos los roles de la base de datos
        roles = Rol.query.all()
        cont = 0
        
        # Comparamos que el nombre ingresado por el usuario no sea igual a uno existente
        if roles != None:
            for rolind in roles:
                if form.nombre.data == rolind.nombre:
                    cont = cont + 1
         
        # Si ya existe el nombre, no permitimos la creacion           
        if cont != 0:
            flash("El nombre de rol ya existe, elija otro", 'error-message')
            return redirect(url_for('roles.crear_rol'))
           
        # Si el nombre aun no existe
        else:
            
            # Obtenemos los permisos seleccionados por el usuario
            lista_permisos = []
            for id_permiso in form.permisos.data:    
                permiso = Permiso.query.filter_by(id=id_permiso).first()
                lista_permisos.append(permiso)
            
            # Creamos el rol
            rol = Rol(form.nombre.data, form.descripcion.data, lista_permisos)
            db.session.add(rol)
            db.session.commit()
        
        # Una vez creado el nuevo rol, se redirecciona a la pagina de administracion
        flash('El rol ha sido registrado con exito')     
        return redirect(url_for('roles.administracion_rol'))
          
    return render_template('rol/crear_rol.html', form = form)


@mod.route('/modificar/<rol>/', methods=['GET', 'POST'])
@permission('MODIFICAR_ROL')

def modificar_rol(rol):
    """
    Muestra en pantalla el formulario de modificacion de roles, valida los datos ingresados por
    el usuario, hace las validaciones de el nombre de usuario nuevo no exista ya en el
    sistema y se hayan ingresado los datos obligatorios. Luego almacena en base de datos los
    cambios
    @param rol: id del rol que se desea modificar
    """
    # Obtenemos el rol seleccionado a ser modificado
    rol_seleccionado = Rol.query.filter_by(id=rol).first()
    
    if rol_seleccionado.nombre in roles_por_defecto:
        # Si el rol seleccionado es un rol por defecto no permitimos la modificacion
        flash('No se puede modificar el rol por defecto %s' % rol_seleccionado.nombre, 
              'error-message')
        return redirect(url_for('roles.administracion_rol'))
    
    else:
    
        # Obtenemos el formulario
        form = RolEditable(request.form)
    
        # Obtenemos todos los permisos que existen en la base de datos
        permisos =Permiso.query.all()
    
        # Hacemos una tupla con el nombre del permisos y su id
        lista_permisos=[]
        for permiso in permisos:
            if permiso.entidad == None:
                aux = ""
            else:
                aux= permiso.entidad.nombre
            
            lista_permisos.append((permiso.id, permiso.nombre+" "+aux))
    
        # Listamos los permisos que existen en el checkbox
        form.permisos.choices = lista_permisos
    
    
        # Validamos los datos ingresados al formulario
        if form.validate_on_submit():
            # Obtenemos todos los roles de la base de datos
            roles = Rol.query.all()
            cont = 0
            
            # Comparamos que el nombre ingresado por el usuario no sea igual a uno existente
            if roles != None:
                for rolind in roles:
                    if form.nombre.data == rolind.nombre:
                        cont = cont + 1
            
            # Si el nombre  existe en el sistema y no es igual al nombre viejo del rol o
            # es una nombre de un rol por defecto. No permitimos la modificacion         
            if (cont != 0 and form.nombre.data != rol_seleccionado.nombre) or (form.nombre.data
                                                                     in roles_por_defecto):
            
                flash("El nombre de rol ya existe, elija otro", 'error-message')
                # Redirigimos a la pagina de modificacion
                return redirect(url_for('roles.modificar_rol', rol = rol_seleccionado.id))
        
            else:
                
                # Si se puede realizar la modificacion
                # Obtenemos los permisos seleccionados por el usuario
                permisos_seleccionados = []
                for id_permiso in form.permisos.data:   
                    permiso = Permiso.query.filter_by(id=id_permiso).first()
                    permisos_seleccionados.append(permiso)
                
                # Realizamos los cambios en los atributos del rol
                rol_seleccionado.setNombre(form.nombre.data)
                rol_seleccionado.setDescripcion(form.descripcion.data)
                rol_seleccionado.setPermisos(permisos_seleccionados)
            
                # Almacenamos el rol modificado en la base de datos
                db.session.add(rol_seleccionado)
                db.session.commit()
                
                # Retornamos a la pagina de administracion de roles
                flash('El rol ha sido registrado con exito')
                return redirect(url_for('roles.administracion_rol'))
        
        # Mostramos en el formulario la descripcion y el nombre actual del rol que se quiere
        # modificar
        form.descripcion.data = rol_seleccionado.descripcion
        form.nombre.data = rol_seleccionado.nombre
            
        # Obtenemos los permisos que el rol seleccionado tiene antes de la modificacion
        permisos_seleccionados = []
        for permiso_sec in rol_seleccionado.permiso:
            permisos_seleccionados.append(permiso_sec.id)
      
        # Mostramos seleccionados esos permisos en el checkbox  
        form.permisos.data = permisos_seleccionados
            
        return render_template('rol/modificar_rol.html', form = form, 
                           rol_seleccionado=rol_seleccionado)
    

@mod.route('/consultar/<rol>/', methods=['GET', 'POST'])
@permission('VER_ROL')
def consultar_rol(rol):
    """
    Muestra en pantalla el formulario de consulta de roles, muestra todos los datos del
    rol seleccionado
    @param rol: id del rol que se desea consultar
    """
    
    # Obtenemos el formulario
    form = RolNoEditable(request.form)
    
    # Obtenemos el rol seleccionado
    rol_seleccionado = Rol.query.filter_by(id=rol).first()
    
    # Hacemos una tupla con el nombre y el id de los permisos del rol
    permisos_seleccionados = []
    for permiso in rol_seleccionado.permiso:
        if permiso.entidad == None:
            aux = ""
        else:
            aux= permiso.entidad.nombre
            
        permisos_seleccionados.append((permiso.id, permiso.nombre+" "+aux))
    
    # Mostramos los permisos que posee el rol   
    form.permisos.choices = permisos_seleccionados
    # Mostramos el nombre del rol
    form.nombre.data = rol_seleccionado.nombre
    #Mostramos la descripcion del sol
    form.descripcion.data = rol_seleccionado.descripcion
    
    
    if form.validate_on_submit():
        
        #Cuando el usuario presiona aceptar, redirigimos a la pagina de administracion de roles
        return redirect(url_for('roles.administracion_rol'))
    
    return render_template('rol/consultar_rol.html', form = form, 
                           rol_seleccionado=rol_seleccionado)
    

@mod.route('/eliminar/<rol>/', methods=['GET', 'POST'])
@permission('ELIMINAR_ROL')
def eliminar_rol(rol):
    """
    Muestra en pantalla el formulario de eliminacion de roles, muestra todos los datos del
    rol seleccionado
    @param rol: id del rol que se desea eliminar
    """
    # Obtenemos el rol seleccionado
    rol_seleccionado = Rol.query.filter_by(id=rol).first()
    usuarios = Usuario.query.all()
    
    cont = 0
    
    for usuario in usuarios:
        if rol_seleccionado in usuario.roles:
            cont = cont +1
    
      
    if rol_seleccionado.nombre in roles_por_defecto:
        
        # Si el rol seleccionado es un rol por defecto no permitimos la modificacion
        flash('No se puede eliminar el rol por defecto %s' % rol_seleccionado.nombre,
               'error-message')
        return redirect(url_for('roles.administracion_rol'))
    
    elif cont!=0:
        
         flash('No se puede eliminar el rol %s , se encuentra asociado con un usuario' % rol_seleccionado.nombre,'error-message')
         return redirect(url_for('roles.administracion_rol'))
    
    else:
    
        # Obtenemos el formulario
        #form = RolNoEditable(request.form)
    
    
        # Hacemos una tupla con el nombre y el id de los permisos del rol
        #permisos_seleccionados = []
        #for permiso in rol_seleccionado.permiso:
        #    if permiso.entidad == None:
        #        aux = ""
        #    else:
        #        aux= permiso.entidad.nombre
        #    permisos_seleccionados.append((permiso.id, permiso.nombre+" "+aux))
    
        #Mostramos la lista de permisos que posee el rol    
        #form.permisos.choices = permisos_seleccionados
        # Mostramos el nombre del rol
        #form.nombre.data = rol_seleccionado.nombre
        # Mostramos la descripcion del rol
        #form.descripcion.data = rol_seleccionado.descripcion
    
        # Cuando le da click en el boton aceptar
        #if form.validate_on_submit():
            
        # Borramos de la base de datos el rol
        db.session.delete(rol_seleccionado)
        db.session.commit()
            
        # Redirigimos a la pagina de administracion de roles
        flash('El rol ha sido eliminado con exito')
        return redirect(url_for('roles.administracion_rol'))
        
        
        #return render_template('rol/eliminar_rol.html', form = form, 
        #                   rol_seleccionado=rol_seleccionado)
    